/**
 * @copyright Copyright (c) 2025 
 * CSG Digital Grid Technology (Guangdong) Co., Ltd.
 * @author xxxcsg
 * @brief misc分区数据操作工具函数库
 * @details 提供misc分区相关的核心功能函数，用于支撑bootloader配置的读写与展示：
 *          1. print_misc_data：打印boot_msg结构体数据（槽位、命令、状态等信息）
 *          2. write_boot_msg：向指定misc设备节点写入boot_msg配置数据
 *          3. read_boot_msg：从指定misc设备节点读取boot_msg配置数据（支持偏移量定位）
 * @note 依赖头文件include/misc_inf.h，需提前定义boot_msg结构体、MISC_OFFSET宏及EOK常量
 * @attention 1. 读写操作需确保设备节点路径正确且具备对应权限；
 *            2. 数据读写严格遵循boot_msg结构体大小，需保证结构体定义在上下游文件中一致
 */
#include "include/misc_inf.h"

void print_misc_data(boot_msg* data) {
        printf("***bootloader message***\n");
        printf("boot.slot: %c\n", data->slot[0]);
        printf("boot.running_slot: %c\n", data->running_slot[0]);
        printf("boot.command: %s\n", data->command);
        printf("boot.status: %s\n", data->status);
        printf("boot.reserved: %s\n", data->reserved);
}

int write_boot_msg(const char* dev, const boot_msg* boot) {
    int ret;
    int fd = open(dev, O_WRONLY);
    if (fd < 0) {
        printf("write_boot_msg open failed : %s\n", strerror(errno));
        return -1;
    }

    ret = write(fd, boot, sizeof(boot_msg));
    if (ret != sizeof(boot_msg)) {
        printf("write_boot_msg fwrite failed : %s\n", strerror(errno));
        close(fd);
        return -1;
    }

    ret = close(fd);
    if (ret != 0) {
        printf("write_boot_msg fclose failed : %s\n", strerror(errno));
        return -1;
    }
    return 0;
}

int read_boot_msg(const char* dev, boot_msg* boot) {
    int ret;
    int fd = open(dev, O_RDONLY);
    if (fd < 0) {
        printf("read_boot_msg open failed : %s\n", strerror(errno));
        return -1;
    }

    boot_msg temp_boot;
    memset(&temp_boot, 0x00, sizeof(boot_msg));

    ret = lseek(fd, MISC_OFFSET, SEEK_SET);
    if (ret != MISC_OFFSET) {
        printf("read_boot_msg lseek failed : %s\n", strerror(errno));
        close(fd);
        return -1;
    }

    ret = read(fd, &temp_boot, sizeof(boot_msg));
    if (ret != sizeof(boot_msg)) {
        printf("read_boot_msg read failed : %s\n", strerror(errno));
        close(fd);
        return -1;
    }

    ret = close(fd);
    if (ret != 0) {
        printf("read_boot_msg fclose failed : %s\n", strerror(errno));
        return -1;
    }

    if (memcpy_s(boot, sizeof(boot_msg), &temp_boot, sizeof(boot_msg)) != EOK) {
        printf("read_boot_msg memcpy failed : %s\n", strerror(errno));
        return -1;
    }
    return 0;
}
